<template>
  <div class="markdown-preview">
    <!-- 工具栏 -->
    <div class="toolbar">
      <div class="left-tools">
        <el-button-group size="small">
          <el-button
            :type="viewMode === 'preview' ? 'primary' : 'default'"
            @click="viewMode = 'preview'"
          >
            <template #icon>
              <IconifyIconOnline icon="ep:view" />
            </template>
            预览
          </el-button>
          <el-button
            :type="viewMode === 'source' ? 'primary' : 'default'"
            @click="viewMode = 'source'"
          >
            <template #icon>
              <IconifyIconOnline icon="ep:document" />
            </template>
            源码
          </el-button>
          <el-button
            :type="viewMode === 'split' ? 'primary' : 'default'"
            @click="viewMode = 'split'"
          >
            <template #icon>
              <IconifyIconOnline icon="ep:grid" />
            </template>
            分屏
          </el-button>
        </el-button-group>
      </div>

      <div class="right-tools">
        <el-button size="small" :loading="loading" @click="handleRefresh">
          <template #icon>
            <IconifyIconOnline icon="ep:refresh" />
          </template>
          刷新预览
        </el-button>
        <el-button size="small" @click="handleCopy">
          <template #icon>
            <IconifyIconOnline icon="ep:document-copy" />
          </template>
          复制内容
        </el-button>
        <el-button size="small" @click="handleFullscreen">
          <template #icon>
            <IconifyIconOnline icon="ep:full-screen" />
          </template>
          全屏
        </el-button>
      </div>
    </div>

    <!-- 内容区域 -->
    <div class="content-area" :class="{ fullscreen: isFullscreen }">
      <!-- 预览模式 -->
      <div v-if="viewMode === 'preview'" class="preview-only">
        <div v-loading="loading" class="markdown-body" v-html="renderedHtml" />
      </div>

      <!-- 源码模式 -->
      <div v-else-if="viewMode === 'source'" class="source-only">
        <el-input
          :model-value="content"
          type="textarea"
          :rows="20"
          readonly
          resize="none"
          class="source-textarea"
        />
      </div>

      <!-- 分屏模式 -->
      <div v-else-if="viewMode === 'split'" class="split-view">
        <div class="split-left">
          <div class="split-header">
            <span>Markdown 源码</span>
          </div>
          <el-input
            :model-value="content"
            type="textarea"
            :rows="20"
            readonly
            resize="none"
            class="source-textarea"
          />
        </div>
        <div class="split-divider" />
        <div class="split-right">
          <div class="split-header">
            <span>预览效果</span>
          </div>
          <div
            v-loading="loading"
            class="markdown-body"
            v-html="renderedHtml"
          />
        </div>
      </div>
    </div>

    <!-- 统计信息 -->
    <div class="stats-bar">
      <div class="stats-item">
        <IconifyIconOnline icon="ep:document" />
        <span>字数: {{ wordCount }}</span>
      </div>
      <div class="stats-item">
        <IconifyIconOnline icon="ep:clock" />
        <span>阅读时长: {{ readingTime }} 分钟</span>
      </div>
      <div v-if="hasCodeBlock" class="stats-item">
        <IconifyIconOnline icon="ep:cpu" />
        <span>包含代码</span>
      </div>
      <div v-if="hasImage" class="stats-item">
        <IconifyIconOnline icon="ep:picture" />
        <span>包含图片</span>
      </div>
      <div v-if="hasTable" class="stats-item">
        <IconifyIconOnline icon="ep:grid" />
        <span>包含表格</span>
      </div>
      <div v-if="hasMath" class="stats-item">
        <IconifyIconOnline icon="ep:data-analysis" />
        <span>包含公式</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from "vue";
import { ElMessage } from "element-plus";
import {
  previewMarkdownApi,
  type MarkdownPreviewParams,
  type MarkdownPreviewResult,
  ArticleManagementUtils
} from "@/api/article-management";
import { MARKDOWN_PREVIEW_CONFIG } from "@/constants/article";

defineOptions({
  name: "MarkdownPreview"
});

// Props
interface Props {
  content: string;
  htmlContent?: string;
  enableRefresh?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  htmlContent: "",
  enableRefresh: true
});

// 响应式数据
const loading = ref(false);
const viewMode = ref<"preview" | "source" | "split">("preview");
const isFullscreen = ref(false);
const previewResult = ref<MarkdownPreviewResult | null>(null);

// 工具函数
const escapeHtml = (text: string): string => {
  const div = document.createElement("div");
  div.textContent = text;
  return div.innerHTML;
};

// 计算属性
const renderedHtml = computed(() => {
  console.log("MarkdownPreview - 计算渲染HTML:", {
    hasHtmlContent: !!props.htmlContent,
    htmlContentLength: props.htmlContent?.length || 0,
    hasPreviewResult: !!previewResult.value,
    previewHtmlLength: previewResult.value?.htmlContent?.length || 0
  });

  if (props.htmlContent) {
    console.log("MarkdownPreview - 使用传入的HTML内容");
    return props.htmlContent;
  }

  if (previewResult.value?.htmlContent) {
    console.log(
      "MarkdownPreview - 使用预览结果HTML:",
      previewResult.value.htmlContent.length
    );
    return previewResult.value.htmlContent;
  }

  // 备用方案：如果没有HTML内容，显示简单的Markdown文本
  if (props.content) {
    console.log("MarkdownPreview - 使用备用方案，显示纯文本");
    return `<div class="fallback-content">
      <div class="fallback-header">
        <strong>⚠️ 预览服务不可用，显示原始内容</strong>
      </div>
      <pre class="fallback-text">${escapeHtml(props.content)}</pre>
    </div>`;
  }

  return "";
});

const wordCount = computed(() => {
  if (previewResult.value) {
    return previewResult.value.wordCount;
  }
  return ArticleManagementUtils.calculateReadingTime(props.content.length);
});

const readingTime = computed(() => {
  if (previewResult.value) {
    return previewResult.value.readingTime;
  }
  return ArticleManagementUtils.calculateReadingTime(props.content.length);
});

const hasCodeBlock = computed(() => {
  return (
    previewResult.value?.hasCodeBlock || /```[\s\S]*?```/.test(props.content)
  );
});

const hasImage = computed(() => {
  return previewResult.value?.hasImage || /!\[.*?\]\(.*?\)/.test(props.content);
});

const hasTable = computed(() => {
  return previewResult.value?.hasTable || /\|.*\|/.test(props.content);
});

const hasMath = computed(() => {
  return previewResult.value?.hasMath || /\$.*\$/.test(props.content);
});

// 监听内容变化
watch(
  () => props.content,
  newContent => {
    console.log("MarkdownPreview - 内容变化:", {
      hasContent: !!newContent,
      contentLength: newContent?.length || 0,
      hasHtmlContent: !!props.htmlContent,
      htmlContentLength: props.htmlContent?.length || 0,
      enableRefresh: props.enableRefresh
    });

    if (newContent && !props.htmlContent && props.enableRefresh) {
      console.log("MarkdownPreview - 触发刷新预览");
      handleRefresh();
    }
  },
  { immediate: true }
);

// 刷新预览
const handleRefresh = async () => {
  console.log("MarkdownPreview - 开始刷新预览:", {
    contentLength: props.content?.length || 0,
    contentPreview: props.content?.substring(0, 100) || ""
  });

  if (!props.content.trim()) {
    console.log("MarkdownPreview - 内容为空，清空预览结果");
    previewResult.value = null;
    return;
  }

  try {
    loading.value = true;
    const params: MarkdownPreviewParams = {
      content: props.content,
      ...MARKDOWN_PREVIEW_CONFIG.defaultFeatures
    };

    console.log("MarkdownPreview - 调用预览API:", params);
    const { data } = await previewMarkdownApi(params);
    console.log("MarkdownPreview - API响应:", data);

    if (data?.code === 200 && data.data) {
      previewResult.value = data.data;
      console.log("MarkdownPreview - 预览结果设置成功:", {
        htmlLength: data.data.htmlContent?.length || 0,
        wordCount: data.data.wordCount
      });
    } else {
      console.warn("MarkdownPreview - API响应格式异常:", data);
      ElMessage.error("预览数据格式异常");
    }
  } catch (error) {
    console.error("MarkdownPreview - 预览失败:", error);
    ElMessage.error("预览失败: " + (error.message || "未知错误"));
  } finally {
    loading.value = false;
  }
};

// 复制内容
const handleCopy = async () => {
  try {
    await navigator.clipboard.writeText(props.content);
    ElMessage.success("内容已复制到剪贴板");
  } catch (error) {
    console.error("复制失败:", error);
    ElMessage.error("复制失败");
  }
};

// 全屏切换
const handleFullscreen = () => {
  isFullscreen.value = !isFullscreen.value;
  if (isFullscreen.value) {
    document.body.style.overflow = "hidden";
  } else {
    document.body.style.overflow = "";
  }
};

// 组件卸载时清理
const cleanup = () => {
  if (isFullscreen.value) {
    document.body.style.overflow = "";
  }
};

// 监听ESC键退出全屏
const handleKeydown = (event: KeyboardEvent) => {
  if (event.key === "Escape" && isFullscreen.value) {
    handleFullscreen();
  }
};

// 生命周期
import { onMounted, onUnmounted } from "vue";

onMounted(() => {
  document.addEventListener("keydown", handleKeydown);
});

onUnmounted(() => {
  document.removeEventListener("keydown", handleKeydown);
  cleanup();
});
</script>

<style lang="scss" scoped>
@import url("@/styles/unified-code-styles.css");

// 响应式设计
@media (width <= 768px) {
  .markdown-preview {
    .toolbar {
      flex-direction: column;
      gap: 12px;
      align-items: stretch;

      .left-tools,
      .right-tools {
        justify-content: center;
      }
    }

    .content-area {
      .split-view {
        flex-direction: column;

        .split-left,
        .split-right {
          flex: none;
          height: 50%;
        }

        .split-left {
          border-right: none;
          border-bottom: 1px solid #dcdfe6;
        }
      }
    }

    .stats-bar {
      flex-wrap: wrap;
      gap: 8px;
    }
  }
}

.markdown-preview {
  overflow: hidden;
  border: 1px solid #dcdfe6;
  border-radius: 4px;

  .toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    background-color: #f5f7fa;
    border-bottom: 1px solid #dcdfe6;

    .left-tools,
    .right-tools {
      display: flex;
      gap: 8px;
    }
  }

  .content-area {
    position: relative;
    min-height: 400px;

    &.fullscreen {
      position: fixed;
      inset: 0;
      z-index: 9999;
      min-height: 100vh;
      background: white;

      .preview-only,
      .source-only,
      .split-view {
        height: calc(100vh - 120px);
      }
    }

    .preview-only {
      padding: 20px;
      overflow-y: auto;
    }

    .source-only {
      padding: 16px;

      .source-textarea {
        :deep(.el-textarea__inner) {
          font-family: Monaco, Menlo, "Ubuntu Mono", monospace;
          font-size: 13px;
          line-height: 1.5;
          border: none;
          box-shadow: none;
        }
      }
    }

    .split-view {
      display: flex;
      height: 100%;

      .split-left,
      .split-right {
        display: flex;
        flex: 1;
        flex-direction: column;
      }

      .split-header {
        padding: 8px 16px;
        font-size: 12px;
        font-weight: 600;
        color: #6c757d;
        background-color: #f8f9fa;
        border-bottom: 1px solid #e9ecef;
      }

      .split-left {
        border-right: 1px solid #dcdfe6;

        .source-textarea {
          flex: 1;

          :deep(.el-textarea__inner) {
            height: 100% !important;
            font-family: Monaco, Menlo, "Ubuntu Mono", monospace;
            font-size: 13px;
            line-height: 1.5;
            resize: none;
            border: none;
            border-radius: 0;
          }
        }
      }

      .split-right {
        .markdown-body {
          flex: 1;
          padding: 20px;
          overflow-y: auto;
        }
      }

      .split-divider {
        width: 1px;
        background-color: #dcdfe6;
      }
    }
  }

  .stats-bar {
    display: flex;
    gap: 16px;
    align-items: center;
    padding: 8px 16px;
    font-size: 12px;
    color: #6c757d;
    background-color: #f8f9fa;
    border-top: 1px solid #dcdfe6;

    .stats-item {
      display: flex;
      gap: 4px;
      align-items: center;

      .iconify {
        font-size: 14px;
      }
    }
  }
}

// 备用方案样式
:deep(.fallback-content) {
  padding: 20px;
  margin: 16px 0;
  background-color: #fff7e6;
  border: 1px solid #ffd591;
  border-radius: 6px;

  .fallback-header {
    padding: 8px 12px;
    margin-bottom: 16px;
    font-size: 14px;
    color: #d46b08;
    background-color: #fff2e8;
    border-radius: 4px;
  }

  .fallback-text {
    max-height: 400px;
    padding: 16px;
    margin: 0;
    overflow-y: auto;
    font-family: Monaco, Menlo, "Ubuntu Mono", monospace;
    font-size: 13px;
    line-height: 1.5;
    color: #262626;
    word-wrap: break-word;
    white-space: pre-wrap;
    background-color: #fafafa;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
  }
}

// Markdown样式
:deep(.markdown-body) {
  font-family:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  color: #24292e;

  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    margin-top: 24px;
    margin-bottom: 16px;
    font-weight: 600;
    line-height: 1.25;
  }

  h1 {
    padding-bottom: 0.3em;
    font-size: 2em;
    border-bottom: 1px solid #eaecef;
  }

  h2 {
    padding-bottom: 0.3em;
    font-size: 1.5em;
    border-bottom: 1px solid #eaecef;
  }

  p {
    margin-bottom: 16px;
  }

  // 使用统一的代码块样式（通过类应用）

  blockquote {
    padding: 0 1em;
    margin-bottom: 16px;
    color: #6a737d;
    border-left: 0.25em solid #dfe2e5;
  }

  table {
    width: 100%;
    margin-bottom: 16px;
    border-collapse: collapse;

    th,
    td {
      padding: 6px 13px;
      border: 1px solid #dfe2e5;
    }

    th {
      font-weight: 600;
      background-color: #f6f8fa;
    }

    tr:nth-child(2n) {
      background-color: #f6f8fa;
    }
  }

  ul,
  ol {
    padding-left: 2em;
    margin-bottom: 16px;
  }

  li {
    margin-bottom: 0.25em;
  }

  img {
    max-width: 100%;
    height: auto;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgb(0 0 0 / 10%);
  }

  a {
    color: #0366d6;
    text-decoration: none;

    &:hover {
      text-decoration: underline;
    }
  }
}
</style>
